package avicit.bdp.dgs.qa.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dgs.qa.dao.SubscribeDAO;
import avicit.bdp.dgs.qa.dto.SubscribeDTO;
import avicit.bdp.dgs.qa.utils.enums.SubscribeType;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.github.pagehelper.Page;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2023-03-30
 * @类说明：SubscribeService
 * @修改记录：
 * @注意事项：
 * @主要功能：质量作业订阅Service
 */
@Service
public class SubscribeService extends BaseService<SubscribeDAO, SubscribeDTO> {
    private static final Logger logger = LoggerFactory.getLogger(SubscribeService.class);

    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 新增订阅人
     * @param subscribeDTO
     * @return
     */
    @Transactional
    public boolean addSubscribe(SubscribeDTO subscribeDTO) {
        checkAddSubscribe(subscribeDTO);

        batchInsert2Db(subscribeDTO);

        return true;
    }

    /**
     * 删除/批量删除订阅人，多个id使用英文逗号隔开
     * @param id
     * @return
     */
    @Transactional
    public int deleteSubscribe(String id) {
        if (StringUtils.isBlank(id)) {
            return 0;
        }

        return this.mapper.deleteSubscribeByCond(null, Arrays.asList(id.trim().split(Constants.COMMA)));
    }

    /**
     * 根据作业ID删除订阅信息
     * @param jobId
     * @return
     */
    @Transactional
    public int deleteSubscribeByJobId(String jobId) {
        if (StringUtils.isBlank(jobId)) {
            return 0;
        }

        return this.mapper.deleteSubscribeByCond(jobId, null);
    }

    /**
     * 修改订阅人
     * @param subscribeDTO
     * @return
     */
    @Transactional
    public boolean updateSubscribe(SubscribeDTO subscribeDTO) {
        checkUpdateValid(subscribeDTO);

        update2Db(subscribeDTO);

        return true;
    }

    /**
     * 查询订阅详情
     * @param id
     * @return
     */
    @Transactional
    public SubscribeDTO getSubscribeDetail(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }

        SubscribeDTO queryRet = this.selectByPrimaryKey(id);
        if (queryRet == null) {
            return null;
        }

        valueConvert(Arrays.asList(queryRet));

        return queryRet;
    }

    /**
     * 分页查询订阅信息
     * @param jobId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Transactional
    public QueryRespBean<SubscribeDTO> querySubscribe(String jobId, Integer pageNo, Integer pageSize) {
        QueryRespBean<SubscribeDTO> queryRespBean = new QueryRespBean<>();

        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
        Page<SubscribeDTO> queryRet = this.mapper.querySubscribeByCond(jobId);
        queryRespBean.setResult(queryRet);

        valueConvert(queryRet.getResult());

        return queryRespBean;
    }

    /**
     * 列举订阅信息
     * @param jobId
     * @return
     */
    @Transactional
    public List<SubscribeDTO> getSubscribeList(String jobId) {
        Page<SubscribeDTO> queryRet = this.mapper.querySubscribeByCond(jobId);
        if (CollectionUtils.isEmpty(queryRet)) {
            return new ArrayList<>();
        }

        valueConvert(queryRet.getResult());
        return queryRet.getResult();
    }

    /**
     * 检查订阅人是否重复订阅
     * @param jobId
     * @param userId
     * @param type
     * @return true:重复；false：不重复
     */
    @Transactional
    public boolean checkValid(String jobId, String userId, Integer type) {
        long count = this.mapper.selectNameCount(jobId, userId, type);
        if (count > 0) {
            return true;
        }

        return false;
    }

    /**
     * 持久化DB
     * @param subscribeDTO
     */
    @SuppressWarnings("mapper中增加批量新增接口，待优化")
    private void batchInsert2Db(SubscribeDTO subscribeDTO) {
        if (subscribeDTO == null) {
            return;
        }

        // 根据jobId、userIdList查询表，获取已创建订阅信息
        List<String> userIdList = Arrays.asList(subscribeDTO.getUserId().trim().split(Constants.COMMA));
        List<SubscribeDTO> existsSubscribeList = this.mapper.getSubscribeListByCond(subscribeDTO.getJobId(), userIdList);

        // 根据jobId+userId去重
        List<String> diffUserIdList = userIdList;
        if (CollectionUtils.isNotEmpty(existsSubscribeList)) {
            List<String> existsUserIdList = existsSubscribeList.stream()
                    .map(SubscribeDTO::getUserId)
                    .collect(Collectors.toList());

            diffUserIdList = (List<String>) CollectionUtils.subtract(userIdList, existsUserIdList);
        }

        // 持久化
        for (String userId : diffUserIdList) {
            subscribeDTO.setId(ComUtil.getId());
            subscribeDTO.setUserId(userId);
            this.insert(subscribeDTO);

            BdpLogUtil.log4Insert(subscribeDTO);
        }
    }

    /**
     * 持久化DB
     * @param subscribeDTO
     */
    private void save2Db(SubscribeDTO subscribeDTO) {
        if (subscribeDTO == null) {
            return;
        }

        // 规则持久化
        subscribeDTO.setId(ComUtil.getId());
        this.insert(subscribeDTO);

        // 审计日志
        BdpLogUtil.log4Insert(subscribeDTO);
    }

    /**
     * 更新到DB
     * @param subscribeDTO
     */
    @SuppressWarnings("当前订阅类型仅支持一种，后续如果支持多种的情况下，Map<userId,DTO>方式会有问题，请注意！")
    private void update2Db(SubscribeDTO subscribeDTO) {
        if (subscribeDTO == null) {
            return;
        }

        List<String> userIdList = Arrays.asList(subscribeDTO.getUserId().trim().split(Constants.COMMA));
        List<SubscribeDTO> existsSubscribeList = this.mapper.getSubscribeListByCond(subscribeDTO.getJobId(), userIdList);
        if (CollectionUtils.isNotEmpty(existsSubscribeList)) {
            Map<String, SubscribeDTO> existsMap = existsSubscribeList.stream()
                    .collect(Collectors.toMap(SubscribeDTO::getUserId, SubscribeDTO -> SubscribeDTO));
            for (String userId : userIdList) {
                if (existsMap.containsKey(userId)) {
                    // 已存在，更新
                    SubscribeDTO oldDto = existsMap.get(userId);
                    oldDto.setType(subscribeDTO.getType());
                    this.updateByPrimaryKeySelective(oldDto);
                } else {
                    // 不存在，新增
                    SubscribeDTO newDto = new SubscribeDTO();
                    newDto.setId(ComUtil.getId());
                    newDto.setJobId(subscribeDTO.getJobId());
                    newDto.setType(subscribeDTO.getType());
                    newDto.setUserId(userId);

                    this.insert(newDto);
                }
            }
        }
    }

    /**
     * 添加订阅时合法性检查
     * @param subscribeDTO
     */
    private void checkAddSubscribe(SubscribeDTO subscribeDTO) {
        if (subscribeDTO == null) {
            throw new BusinessException("入参为空.");
        }
        if (StringUtils.isBlank(subscribeDTO.getUserId())) {
            throw new BusinessException("用户名ID为空.");
        }
        if (StringUtils.isBlank(subscribeDTO.getJobId())) {
            throw new BusinessException("作业ID为空.");
        }
        if (subscribeDTO.getType() == null) {
            throw new BusinessException("订阅类型为空.");
        }
    }

    /**
     * 修改订阅时合法性检查
     * @param subscribeDTO
     */
    private void checkUpdateValid(SubscribeDTO subscribeDTO) {
        if (subscribeDTO == null) {
            throw new BusinessException("入参为空.");
        }
        if (StringUtils.isBlank(subscribeDTO.getId())) {
            throw new BusinessException("订阅信息主键ID为空.");
        }
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     * @param dtoList
     */
    private void valueConvert(List<SubscribeDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }

        // 订阅人名字
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (SubscribeDTO dto : dtoList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getUserId());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (SubscribeDTO dto : dtoList) {
                dto.setUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getUserId()));
            }
        }

        // 设置枚举类型
        for (SubscribeDTO dto : dtoList) {
            dto.setTypeName(SubscribeType.getDescByCode(dto.getType()));
        }
    }
}
